﻿using System;
using System.Collections.Generic;
using SharedTypes;

namespace GeneticAlgorithm
{
    /// <summary>
    /// Хромосома – это возможное решение нашей задачи, не важно какое, правильное или нет.
    /// </summary>
    public class Chromosome : IComparable, ICloneable
    {
        #region Members
        /// <summary>
        /// Ген – элементарная частичка информации, в рамках данной задачи, т.е. параметер
        /// </summary>
        private IDictionary<int, LinkedParameter> gens;

        /// <summary>
        /// Приспасабливаемость
        /// </summary>
        private double fitness;

        /// <summary>
        /// Длительность архивации с данным набором параметров
        /// </summary>
        private TimeSpan timeElapsed;
        #endregion // Members

        #region Properties
        /// <summary>
        /// 
        /// </summary>
        public IDictionary<int, LinkedParameter> Gens
        {
            get { return gens; }
            set { gens = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public double Fitness
        {
            get { return fitness; }
            set { fitness = value; }
        }

        public double Compression
        {
            get;
            set;
        }

        public TimeSpan TimeElapsed
        {
            get { return timeElapsed; }
            set { this.timeElapsed = value; }
        }
        #endregion // Properties

        #region Constructor
        /// <summary>
        /// конструктор
        /// </summary>
        public Chromosome(IDictionary<int, LinkedParameter> parameters)
        {
            gens = parameters;
            foreach (KeyValuePair<int, LinkedParameter> parameter in gens)
            {
                parameter.Value.parameter.PlaceValuesInRandomState();
            }
        }
        #endregion // Constructor

        #region Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int CompareTo(object obj)
        {
            int result = -1;
            try
            {
                Chromosome tmp = obj as Chromosome;
                if (fitness == tmp.fitness)
                {
                    result = 0;
                }
                else if (fitness > tmp.fitness)
                {
                    result = 1;
                }
            }
            catch
            {
                //do nothing
            }
            return result;
        }

        /// <summary>
        /// Метод для клонированя объекта
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            IDictionary<int, LinkedParameter> currentParameter = new Dictionary<int, LinkedParameter>();
            foreach (KeyValuePair<int, LinkedParameter> parameter in gens)
            {
                currentParameter.Add(parameter.Key, parameter.Value);
            }
            Chromosome clone = new Chromosome(currentParameter);
            clone.fitness = fitness;
            return clone;
        }
        #endregion // Methods
    }
}
